home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / src / openlook.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-17  |  10.5 KB  |  432 lines

  1. /*
  2.  * openlook.c - OPEN LOOK (tm) compatibility stuff
  3.  * 
  4.  *  Window Maker window manager
  5.  * 
  6.  *  Copyright (c) 1998, 1999 Alfredo K. Kojima
  7.  * 
  8.  *  This program is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2 of the License, or
  11.  *  (at your option) any later version.
  12.  *
  13.  *  This program is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with this program; if not, write to the Free Software
  20.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  21.  *  USA.
  22.  */
  23.  
  24. /*
  25.  * Semantics and hint information taken from olwm code
  26.  */
  27.  
  28. #include "wconfig.h"
  29.  
  30. #ifdef OLWM_HINTS
  31.  
  32.  
  33. #include <X11/Xlib.h>
  34. #include <X11/Xutil.h>
  35. #include <X11/Xatom.h>
  36.  
  37. #include <stdlib.h>
  38. #include <stdio.h>
  39. #include <string.h>
  40.  
  41.  
  42. #include "WindowMaker.h"
  43.  
  44. #include "wcore.h"
  45. #include "framewin.h"
  46. #include "window.h"
  47. #include "properties.h"
  48. #include "icon.h"
  49. #include "client.h"
  50. #include "funcs.h"
  51.  
  52. #include "openlook.h"
  53.  
  54.  
  55. /* pin states */
  56. #define OL_PIN_OUT 0
  57. #define OL_PIN_IN 1
  58.  
  59. /* flags */
  60. #define OL_DECORATION_HEADER      (1<<0)
  61. #define OL_DECORATION_FOOTER      (1<<1)
  62. #define OL_DECORATION_PUSHPIN     (1<<2)
  63. #define OL_DECORATION_CLOSEBUTTON (1<<3)
  64. #define OL_DECORATION_RESIZEABLE  (1<<4)
  65. #define OL_DECORATION_ICONNAME    (1<<5)
  66. #define OL_DECORATION_WARPTOPIN   (1<<6)
  67. #define OL_DECORATION_NONE        (1<<7)
  68.  
  69.  
  70.  
  71. typedef struct {
  72.     long flags;
  73.     Atom winType;
  74.     Atom menuType;
  75.     long pinInitState;
  76.     long cancel;
  77. } OLHints;
  78.  
  79. #define OL_WINTYPE    (1<<0)
  80. #define OL_MENUTYPE    (1<<1)
  81. #define OL_PINSTATE    (1<<2)
  82. #define OL_CANCEL    (1<<3)
  83.  
  84.  
  85.  
  86. typedef struct {
  87.     unsigned used:1;
  88.  
  89.     unsigned semantic:1;
  90.  
  91.     unsigned semantic_compose:1;
  92.     unsigned semantic_capslock:1;
  93.     unsigned semantic_numlock:1;
  94.     unsigned semantic_scrolllock:1;
  95. } WOLWindowState;
  96.  
  97.  
  98. static Atom _XA_SUN_WM_PROTOCOLS = 0;
  99.  
  100. #ifdef unused
  101. static Bool
  102. getWindowState(Window win, OLWindowState *state)
  103. {
  104.     static Atom _XA_SUN_WINDOW_STATE = 0;
  105.     unsigned long *data;
  106.  
  107.     if (!_XA_SUN_WINDOW_STATE) {
  108.     _XA_SUN_WINDOW_STATE = XInternAtom(dpy, "_SUN_WINDOW_STATE", False);
  109.     }
  110.  
  111.     data = (unsigned long*)PropGetCheckProperty(win, _XA_SUN_WINDOW_STATE,
  112.                         XA_INTEGER, 32, 2, NULL);
  113.  
  114.     if (!data) {
  115.     return False;
  116.     }
  117.     
  118.     state->flags = data[0];
  119.     state->state = data[1];
  120.  
  121.     XFree(data);
  122.     
  123.     return True;
  124. }
  125. #endif
  126.  
  127. static Bool
  128. getWindowHints(Window window, OLHints *hints)
  129. {
  130.     long *data;
  131.     int count;
  132.     static Atom _XA_OL_WIN_ATTR = 0;
  133.  
  134.     if (!_XA_OL_WIN_ATTR) {
  135.     _XA_OL_WIN_ATTR = XInternAtom(dpy, "_OL_WIN_ATTR", False);
  136.     }
  137.  
  138.     data = (long*)PropGetCheckProperty(window, _XA_OL_WIN_ATTR, 
  139.                        _XA_OL_WIN_ATTR, 32, 0, &count);
  140.  
  141.     if (!data)
  142.     return False;
  143.  
  144.     if (count == 3) {
  145.     /* old format */
  146.  
  147.     hints->flags = OL_WINTYPE|OL_MENUTYPE|OL_PINSTATE;
  148.     hints->winType = data[0];
  149.     hints->menuType = data[1];
  150.     hints->pinInitState = data[2];
  151.     hints->cancel = 0;
  152.  
  153.     } else if (count == 5) {
  154.     /* new format */
  155.  
  156.     hints->flags = data[0];
  157.     hints->winType = data[1];
  158.     hints->menuType = data[2];
  159.     hints->pinInitState = data[3];
  160.     hints->cancel = data[4];
  161.  
  162.     } else {
  163.     XFree(data);
  164.     return False;
  165.     }
  166.  
  167.     XFree(data);
  168.  
  169.     /* do backward compatibility stuff */
  170.     if (hints->flags & OL_PINSTATE) {
  171.     static Atom pinIn = 0, pinOut;
  172.     
  173.     if (!pinIn) {
  174.         pinIn = XInternAtom(dpy, "_OL_PIN_IN", False);
  175.         pinOut = XInternAtom(dpy, "_OL_PIN_OUT", False);
  176.     }
  177.     
  178.     if (hints->pinInitState == pinIn)
  179.         hints->pinInitState = OL_PIN_IN;
  180.     else if (hints->pinInitState == pinOut)
  181.         hints->pinInitState = OL_PIN_OUT;
  182.     }
  183.  
  184.     return True;
  185. }
  186.  
  187.  
  188.  
  189.  
  190. static void
  191. applyDecorationHints(Window win, int *flags)
  192. {
  193.     Atom *atoms;
  194.     static Atom _XA_OL_DECOR_ADD = 0;
  195.     static Atom _XA_OL_DECOR_DEL = 0;
  196.     static Atom _XA_CLOSE, _XA_FOOTER, _XA_RESIZE, _XA_HEADER, _XA_PIN,
  197.     _XA_ICONNAME;
  198.     int count;
  199.     int i;
  200.  
  201.     if (!_XA_OL_DECOR_DEL) {
  202.     _XA_OL_DECOR_ADD = XInternAtom(dpy, "_OL_DECOR_ADD", False);
  203.     _XA_OL_DECOR_DEL = XInternAtom(dpy, "_OL_DECOR_DEL", False);
  204.  
  205.     _XA_CLOSE = XInternAtom(dpy, "_OL_DECOR_CLOSE", False);
  206.     _XA_FOOTER = XInternAtom(dpy, "_OL_DECOR_FOOTER", False);
  207.     _XA_RESIZE = XInternAtom(dpy, "_OL_DECOR_RESIZE", False);
  208.     _XA_HEADER = XInternAtom(dpy, "_OL_DECOR_HEADER", False);
  209.     _XA_PIN = XInternAtom(dpy, "_OL_DECOR_PIN", False);
  210.     _XA_ICONNAME = XInternAtom(dpy, "_OL_DECOR_ICON_NAME", False);
  211.     }
  212.  
  213.     atoms = (Atom*)PropGetCheckProperty(win, _XA_OL_DECOR_ADD, XA_ATOM, 32, 0, 
  214.                     &count);
  215.     if (atoms) {
  216.     for (i=0; i < count; i++) {
  217.         if (atoms[i] == _XA_CLOSE)
  218.         *flags |= OL_DECORATION_CLOSEBUTTON;
  219.         else if (atoms[i] == _XA_FOOTER)
  220.         *flags |= OL_DECORATION_FOOTER;
  221.         else if (atoms[i] == _XA_RESIZE)
  222.         *flags |= OL_DECORATION_RESIZEABLE;
  223.         else if (atoms[i] == _XA_HEADER)
  224.         *flags |= OL_DECORATION_HEADER;
  225.         else if (atoms[i] == _XA_PIN)
  226.         *flags |= OL_DECORATION_PUSHPIN;
  227.         else if (atoms[i] == _XA_ICONNAME)
  228.         *flags |= OL_DECORATION_ICONNAME;
  229.     }
  230.     XFree(atoms);
  231.     }
  232.  
  233.     atoms = (Atom*)PropGetCheckProperty(win, _XA_OL_DECOR_DEL, XA_ATOM, 32, 0, 
  234.                     &count);
  235.     if (atoms) {
  236.     for (i=0; i < count; i++) {
  237.         if (atoms[i] == _XA_CLOSE)
  238.         *flags &= ~OL_DECORATION_CLOSEBUTTON;
  239.         else if (atoms[i] == _XA_FOOTER)
  240.         *flags &= ~OL_DECORATION_FOOTER;
  241.         else if (atoms[i] == _XA_RESIZE)
  242.         *flags &= ~OL_DECORATION_RESIZEABLE;
  243.         else if (atoms[i] == _XA_HEADER)
  244.         *flags &= ~OL_DECORATION_HEADER;
  245.         else if (atoms[i] == _XA_PIN)
  246.         *flags &= ~OL_DECORATION_PUSHPIN;
  247.         else if (atoms[i] == _XA_ICONNAME)
  248.         *flags &= ~OL_DECORATION_ICONNAME;
  249.     }
  250.     XFree(atoms);
  251.     }
  252. }
  253.  
  254.  
  255. void
  256. wOLWMInitStuff(WScreen *scr)
  257. {
  258.     static Atom _SUN_OL_WIN_ATTR_5;
  259.  
  260.     if (!_XA_SUN_WM_PROTOCOLS) {
  261.     _XA_SUN_WM_PROTOCOLS = XInternAtom(dpy, "_SUN_WM_PROTOCOLS", False);
  262.     _SUN_OL_WIN_ATTR_5 = XInternAtom(dpy, "_SUN_OL_WIN_ATTR_5", False);
  263.     }
  264.  
  265.     XChangeProperty(dpy, scr->root_win, _XA_SUN_WM_PROTOCOLS, XA_ATOM, 32,
  266.             PropModeReplace, (unsigned char*)&_SUN_OL_WIN_ATTR_5, 1);
  267. }
  268.  
  269.  
  270. void
  271. wOLWMChangePushpinState(WWindow *wwin, Bool state)
  272. {
  273.     static Atom pinState = 0;
  274.  
  275.     if (!pinState) {
  276.     pinState = XInternAtom(dpy, "_OL_PIN_STATE", False);
  277.     }
  278.  
  279.     XChangeProperty(dpy, wwin->client_win, pinState, XA_INTEGER, 32,
  280.             PropModeReplace, (unsigned char *)&state, 1);
  281. }
  282.  
  283.  
  284. void
  285. wOLWMShutdown(WScreen *scr)
  286. {
  287.     XDeleteProperty(dpy, scr->root_win, _XA_SUN_WM_PROTOCOLS);
  288. }
  289.  
  290.  
  291. #ifdef unfinished
  292. void
  293. wOLWMUpdateWindowState(WWindow *wwin)
  294. {
  295.     if (wwin->ol_window_state.used) {
  296.     if (wwin->ol_window_state.semantic) {
  297.         if (wwin->ol_window_state.semantic_compose)
  298.         setComposeLed(True);
  299.         else
  300.         setComposeLed(False);
  301.     }
  302.     } else {
  303.     setComposeLed(False);
  304.     }
  305. }
  306. #endif /* unfinished */
  307.  
  308. void
  309. wOLWMCheckClientHints(WWindow *wwin)
  310. {
  311.     OLHints hints;
  312.     static Atom WT_BASE = 0, WT_CMD, WT_NOTICE, WT_HELP, WT_OTHER;
  313.     static Atom MT_FULL, MT_LIMITED, MT_NONE;
  314.     int decoration;
  315.     int pinInitState = OL_PIN_IN;
  316.     Atom menuType;
  317.  
  318.     if (!WT_BASE) {
  319.     WT_BASE = XInternAtom(dpy, "_OL_WT_BASE", False);
  320.     WT_CMD = XInternAtom(dpy, "_OL_WT_CMD", False);
  321.     WT_NOTICE = XInternAtom(dpy, "_OL_WT_NOTICE", False);
  322.     WT_HELP = XInternAtom(dpy, "_OL_WT_HELP", False);
  323.     WT_OTHER = XInternAtom(dpy, "_OL_WT_OTHER", False);
  324.  
  325.     MT_FULL = XInternAtom(dpy, "_OL_MENU_FULL", False);
  326.     MT_LIMITED = XInternAtom(dpy, "_OL_MENU_LIMITED", False);
  327.     MT_NONE = XInternAtom(dpy, "_OL_NONE", False);
  328.     }
  329.  
  330.     /* get attributes */
  331.  
  332.     if (!getWindowHints(wwin->client_win, &hints) ||
  333.     !(hints.flags & OL_WINTYPE)) {
  334.  
  335.     decoration = OL_DECORATION_CLOSEBUTTON|OL_DECORATION_RESIZEABLE
  336.         |OL_DECORATION_HEADER|OL_DECORATION_ICONNAME;
  337.  
  338.     menuType = MT_FULL;
  339.  
  340.     } else {
  341.     if (hints.winType == WT_BASE) {
  342.  
  343.         decoration = OL_DECORATION_CLOSEBUTTON|OL_DECORATION_RESIZEABLE
  344.         |OL_DECORATION_HEADER|OL_DECORATION_ICONNAME;
  345.  
  346.         menuType = MT_FULL;
  347.  
  348.     } else if (hints.winType == WT_CMD) {
  349.  
  350.         decoration = OL_DECORATION_PUSHPIN|OL_DECORATION_RESIZEABLE
  351.         |OL_DECORATION_HEADER|OL_DECORATION_ICONNAME;
  352.  
  353.         menuType = MT_LIMITED;
  354.  
  355.     } else if (hints.winType == WT_NOTICE) {
  356.  
  357.         decoration = OL_DECORATION_ICONNAME;
  358.         menuType = MT_NONE;
  359.  
  360.     } else if (hints.winType == WT_HELP) {
  361.  
  362.         decoration = OL_DECORATION_PUSHPIN|OL_DECORATION_HEADER
  363.         |OL_DECORATION_ICONNAME|OL_DECORATION_WARPTOPIN;
  364.         menuType = MT_LIMITED;
  365.         
  366.     } else if (hints.winType == WT_OTHER) {
  367.  
  368.         decoration = OL_DECORATION_ICONNAME;
  369.         menuType = MT_NONE;
  370.  
  371.         if (hints.flags & OL_MENUTYPE) {
  372.         menuType = hints.menuType;
  373.         }
  374.     }
  375.  
  376.     if (hints.flags & OL_PINSTATE) {
  377.         pinInitState = hints.pinInitState;
  378.     } else {
  379.         pinInitState = OL_PIN_OUT;
  380.     }
  381.     }
  382.  
  383.     /* mask attributes with decoration hints */
  384.     applyDecorationHints(wwin->client_win, &decoration);
  385.  
  386.     if ((decoration & OL_DECORATION_CLOSEBUTTON)
  387.     && (decoration & OL_DECORATION_PUSHPIN))
  388.     decoration &= ~OL_DECORATION_CLOSEBUTTON;
  389.  
  390.     if (!(decoration & OL_DECORATION_PUSHPIN))
  391.     decoration &= ~OL_DECORATION_WARPTOPIN;
  392.  
  393.  
  394.     /* map the hints to our attributes */
  395.     if (menuType == MT_FULL)
  396.     wwin->flags.olwm_limit_menu = 0;
  397.     else
  398.     wwin->flags.olwm_limit_menu = 1;
  399.  
  400.     /* this is a transient-like window */
  401.     if (hints.winType == WT_CMD) {
  402.     wwin->client_flags.olwm_transient = 1;
  403.     }
  404.  
  405.     /*
  406.      * Emulate olwm pushpin.
  407.      * If the initial state of the pin is in, then put the normal close
  408.      * button. If not, make the close button different and when the
  409.      * user moves the window or clicks in the close button, turn it
  410.      * into a normal close button.
  411.      */
  412.     if ((decoration & OL_DECORATION_PUSHPIN) && pinInitState==OL_PIN_OUT) {
  413.     wwin->flags.olwm_push_pin_out = 1;
  414.  
  415.     wOLWMChangePushpinState(wwin, False);
  416.     } else {
  417.     wOLWMChangePushpinState(wwin, True);
  418.     }
  419.  
  420.     if (!(decoration & OL_DECORATION_RESIZEABLE)) {
  421.     wwin->client_flags.no_resizable = 1;
  422.     wwin->client_flags.no_resizebar = 1;
  423.     }
  424.  
  425.     if (decoration & OL_DECORATION_WARPTOPIN) {
  426.     wwin->client_flags.olwm_warp_to_pin = 1;
  427.     }
  428.  
  429. }
  430. #endif
  431.  
  432.